﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using DTcms.Core.API.Filters;
using DTcms.Core.Common.Emum;
using DTcms.Core.Common.Extensions;
using DTcms.Core.Common.Helper;
using DTcms.Core.IServices;
using DTcms.Core.Model.Models;
using DTcms.Core.Model.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;

namespace DTcms.Core.API.Controllers
{
    /// <summary>
    /// 会员充值记录
    /// </summary>
    [Route("member/recharge")]
    [ApiController]
    public class MemberRechargeController : ControllerBase
    {
        private readonly IMemberRechargeService _memberRechargeService;
        private readonly IUserService _userService;
        private readonly IMapper _mapper;

        public MemberRechargeController(IMemberRechargeService memberRechargeService, 
            IUserService userService, IMapper mapper)
        {
            _memberRechargeService = memberRechargeService;
            _userService = userService;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取总记录数量
        /// 示例：/member/recharge/view/count
        /// </summary>
        [HttpGet("view/count")]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.View)]
        public async Task<IActionResult> GetCount([FromQuery] ReportParameter searchParam)
        {
            var result = await _memberRechargeService.QueryCountAsync(
                x => (searchParam.Status <= -1 || x.Status == searchParam.Status)
                && (searchParam.StartTime == null || DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0));
            //返回成功200
            return Ok(result);
        }

        /// <summary>
        /// 获取总记录金额
        /// 示例：/member/recharge/view/amount
        /// </summary>
        [HttpGet("view/amount")]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.View)]
        public async Task<IActionResult> GetAmount([FromQuery] ReportParameter searchParam)
        {
            if (searchParam.StartTime == null)
            {
                searchParam.StartTime = DateTime.Now.AddHours(-DateTime.Now.Hour + 1);
            }
            var result = await _memberRechargeService.QueryAmountAsync(
                x => (searchParam.Status <= -1 || x.Status == searchParam.Status)
                && (DateTime.Compare(x.AddTime, searchParam.StartTime.GetValueOrDefault()) >= 0));
            //返回成功200
            return Ok(result);
        }

        /// <summary>
        /// 根据ID获取数据
        /// 示例：/member/recharge/1
        /// </summary>
        [HttpGet("{id}")]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.View)]
        public async Task<IActionResult> GetById([FromRoute] long id, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //查询数据库获取实体
            var resultFrom = await _memberRechargeService.QueryAsync(x => x.Id == id);
            if (resultFrom == null)
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            //根据字段进行塑形
            var result = resultFrom.ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/member/recharge?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.View)]
        public async Task<IActionResult> GetList([FromQuery] BaseParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy.IsNotNullOrEmpty()
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _memberRechargeService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => (searchParam.Keyword.IsNotNullOrEmpty() ? x.UserName.Contains(searchParam.Keyword) : true),
                searchParam.OrderBy.IsNotNullOrWhiteSpace() ? searchParam.OrderBy : "-AddTime,-Id"
                );
            if (list == null || list.Count() <= 0)
            {
                return NotFound(ResponseMessage.Error("暂无查询到记录"));
            }

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //根据字段进行塑形，注意因为没有使用AotoMapper，所以要转换成Enumerable
            var resultDto = list.AsEnumerable<MemberRechargeDto>().ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 添加一条记录
        /// 示例：/member/recharge
        /// </summary>
        [HttpPost]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.Add)]
        public async Task<IActionResult> Add([FromBody] MemberRechargeEditDto modelDto)
        {
            //保存充值记录
            var model = await _memberRechargeService.AddAsync(modelDto);
            //重新联合查询
            var result = await _memberRechargeService.QueryAsync(x => x.Id == model.Id);
            return Ok(result);
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/member/recharge/1
        /// </summary>
        [HttpDelete("{id}")]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.Delete)]
        public async Task<IActionResult> Delete([FromRoute] long id)
        {
            //检查记录是否存在
            if (!await _memberRechargeService.ExistsAsync<MemberRecharge>(x => x.Id == id))
            {
                return NotFound(ResponseMessage.Error($"数据{id}不存在或已删除"));
            }
            var result = await _memberRechargeService.DeleteAsync<MemberRecharge>(x => x.Id == id);

            return NoContent();
        }

        /// <summary>
        /// 批量删除记录
        /// 示例：/member/recharge?ids=1,2,3
        /// </summary>
        [HttpDelete]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.Delete)]
        public async Task<IActionResult> DeleteByIds([FromQuery] string Ids)
        {
            //检查参数是否为空
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var listIds = Ids.ToIEnumerable<long>();
            if (listIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //执行批量删除操作
            await _memberRechargeService.DeleteAsync<MemberRecharge>(x => listIds.Contains(x.Id));
            return NoContent();
        }

        /// <summary>
        /// 完成充值订单
        /// 示例：/member/recharge?ids=1,2,3
        /// </summary>
        [HttpPut]
        [Authorize]
        [AuthorizeFilter("MemberRecharge", ActionType.Edit)]
        public async Task<IActionResult> Complete([FromQuery] string Ids)
        {
            //检查参数是否为空
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //将ID列表转换成IEnumerable
            var listIds = Ids.ToIEnumerable<long>();
            if (listIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //将符合条件的一次查询出来
            var list = await _memberRechargeService.QueryListAsync<MemberRecharge>(0, x => x.Status == 0 && listIds.Contains(x.Id));
            //执行批量删除操作
            foreach (var modelt in list)
            {
                await _memberRechargeService.CompleteAsync(modelt.RechargeNo);
            }
            return NoContent();
        }

        #region 前台调用接口============================
        /// <summary>
        /// 根据订单号获取数据
        /// 示例：/account/rechargeno/RN2021031...
        /// </summary>
        [HttpGet("/account/rechargeno/{rechargeNo}")]
        [Authorize]
        public async Task<IActionResult> AccountGetByNo([FromRoute] string rechargeNo, [FromQuery] BaseParameter param)
        {
            //检测参数是否合法
            if (!param.Fields.IsPropertyExists<MemberRecharge>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的塑性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                return BadRequest(ResponseMessage.Error("用户尚未登录"));
            }

            //查询数据库获取实体
            var model = await _memberRechargeService.QueryAsync(x => x.UserId == userId && x.RechargeNo == rechargeNo, WriteRoRead.Write);
            if (model == null)
            {
                return BadRequest(ResponseMessage.Error($"充值单号不存在或已删除"));
            }
            //使用AutoMapper转换成ViewModel，根据字段进行塑形
            var result = _mapper.Map<MemberRechargeDto>(model).ShapeData(param.Fields);
            return Ok(result);
        }

        /// <summary>
        /// 获取指定数量列表
        /// 示例：/account/recharge/view/10
        /// </summary>
        [HttpGet("/account/recharge/view/{top}")]
        [Authorize]
        public async Task<IActionResult> AccountList([FromRoute] int top, [FromQuery] BaseParameter searchParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy.IsNotNullOrEmpty()
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();

            //获取数据库列表
            var list = await _memberRechargeService.QueryListAsync(top,
                x => x.UserId == userId
                && (searchParam.Status <= 0 || x.Status == searchParam.Status)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || x.UserName.Contains(searchParam.Keyword)),
                searchParam.OrderBy.IsNotNullOrWhiteSpace() ? searchParam.OrderBy : "-AddTime,-Id");

            //根据字段进行塑形，注意因为没有使用AotoMapper，所以要转换成Enumerable
            var resultDto = list.AsEnumerable<MemberRechargeDto>().ShapeData(searchParam.Fields);
            //返回成功200
            return Ok(resultDto);
        }

        /// <summary>
        /// 获取分页列表
        /// 示例：/account/recharge?pageSize=10&pageIndex=1
        /// </summary>
        [HttpGet("/account/recharge")]
        [Authorize]
        public async Task<IActionResult> AccountList([FromQuery] BaseParameter searchParam, [FromQuery] PageParamater pageParam)
        {
            //检测参数是否合法
            if (searchParam.OrderBy.IsNotNullOrEmpty()
                && !searchParam.OrderBy.Replace("-", "").IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的排序参数"));
            }
            if (!searchParam.Fields.IsPropertyExists<MemberRechargeDto>())
            {
                return BadRequest(ResponseMessage.Error("请输入正确的属性参数"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();

            //获取数据列表，如果ID大于0则查询该用户下所有的列表
            var list = await _memberRechargeService.QueryPageAsync(
                pageParam.PageSize,
                pageParam.PageIndex,
                x => x.UserId == userId
                && (searchParam.Status <= 0 || x.Status == searchParam.Status)
                && (!searchParam.Keyword.IsNotNullOrEmpty() || x.UserName.Contains(searchParam.Keyword)),
                searchParam.OrderBy.IsNotNullOrWhiteSpace() ? searchParam.OrderBy : "-AddTime,-Id");
            if (list == null || list.Count() <= 0)
            {
                return NotFound(ResponseMessage.Error("暂无查询到记录"));
            }

            //x-pagination
            var paginationMetadata = new
            {
                totalCount = list.TotalCount,
                pageSize = list.PageSize,
                pageIndex = list.PageIndex,
                totalPages = list.TotalPages
            };
            Response.Headers.Add("x-pagination", SerializeHelper.SerializeObject(paginationMetadata));

            //根据字段进行塑形，注意因为没有使用AotoMapper，所以要转换成Enumerable
            var resultDto = list.AsEnumerable<MemberRechargeDto>().ShapeData(searchParam.Fields);
            return Ok(resultDto);
        }

        /// <summary>
        /// 账户充值
        /// 示例：/account/recharge
        /// </summary>
        [HttpPost("/account/recharge")]
        [Authorize]
        public async Task<IActionResult> AccountAdd([FromBody] MemberRechargeEditDto modelDto)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                return BadRequest(ResponseMessage.Error("用户尚未登录"));
            }
            modelDto.UserId = userId;
            //保存数据
            var result = await _memberRechargeService.AddAsync(modelDto);
            return Ok(result);
        }

        /// <summary>
        /// 批量删除记录
        /// 示例：/account/recharge?ids=1,2,3
        /// </summary>
        [HttpDelete("/account/recharge")]
        [Authorize]
        public async Task<IActionResult> AccountDeleteByIds([FromQuery] string Ids)
        {
            //检查参数是否为空
            if (Ids == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不可为空"));
            }
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                return BadRequest(ResponseMessage.Error("用户尚未登录"));
            }
            //将ID列表转换成IEnumerable
            var listIds = Ids.ToIEnumerable<long>();
            if (listIds == null)
            {
                return BadRequest(ResponseMessage.Error("传输参数不符合规范"));
            }
            //执行批量删除操作
            await _memberRechargeService.DeleteAsync<MemberRecharge>(x => listIds.Contains(x.Id) && x.UserId == userId);
            return NoContent();
        }

        /// <summary>
        /// 删除一条记录
        /// 示例：/account/recharge/1
        /// </summary>
        [HttpDelete("/account/recharge/{id}")]
        [Authorize]
        public async Task<IActionResult> AccountDelete([FromRoute] long id)
        {
            //获取登录用户ID
            int userId = await _userService.GetUserIdAsync();
            if (userId == 0)
            {
                return BadRequest(ResponseMessage.Error("用户尚未登录"));
            }
            //检查记录是否存在
            if (!await _memberRechargeService.ExistsAsync<MemberRecharge>(x => x.Id == id && x.UserId == userId))
            {
                return BadRequest(ResponseMessage.Error($"数据不存在或已删除"));
            }
            var result = await _memberRechargeService.DeleteAsync<MemberRecharge>(x => x.Id == id && x.UserId == userId);

            return NoContent();
        }

        /// <summary>
        /// 更改支付方式
        /// 示例：/account/recharge/payment
        /// </summary>
        [HttpPut("/account/recharge/payment")]
        [Authorize]
        public async Task<IActionResult> Payment([FromBody] MemberRechargePaymentDto modelDto)
        {
            var result = await _memberRechargeService.PayAsync(modelDto);
            if (result)
            {
                return NoContent();
            }
            return BadRequest(ResponseMessage.Error("保存过程中发生了错误"));
        }
        #endregion
    }
}
